package wiki.hitime.stl.daq.manager;

import wiki.hitime.stl.daq.bean.bo.MsgRuleConfigFieldBO;
import wiki.hitime.stl.daq.bean.db.DaqMsgRuleDetailConfig;
import wiki.hitime.stl.daq.bean.dto.manage.MsgRuleDetailConfigDTO;
import wiki.hitime.stl.daq.bean.dto.req.MsgRuleDetailConfigListReqDTO;
import wiki.hitime.stl.daq.mapper.DaqMsgRuleDetailConfigMapper;
import wiki.hitime.stl.daq.service.factory.DataMsgFactory;
import wiki.hitime.stl.daq.support.ContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangdaoping
 * @create 2019-07-18 15:31
 */
@Service
public class DaqMsgRuleDetailConfigManager {

    private DaqMsgRuleDetailConfigMapper daqMsgRuleDetailConfigMapper;

    public DaqMsgRuleDetailConfigManager(DaqMsgRuleDetailConfigMapper daqMsgRuleDetailConfigMapper) {
        this.daqMsgRuleDetailConfigMapper = daqMsgRuleDetailConfigMapper;
    }

    /**
     * 加载消息配置信息
     *
     * @param msgRuleId 消息规则编号
     * @return
     */
    public Map<String, String> loadMsgRuleDetailConfig(Long msgRuleId) {
        Example selectExample = new Example(DaqMsgRuleDetailConfig.class, true, true);
        selectExample.createCriteria().andEqualTo("msgRuleId", msgRuleId).andEqualTo("isDelete", Boolean.FALSE);
        List<DaqMsgRuleDetailConfig> detailConfigList = daqMsgRuleDetailConfigMapper.selectByExample(selectExample);
        Map<String, String> configMap = new HashMap<>(detailConfigList.size());
        for (DaqMsgRuleDetailConfig config : detailConfigList) {
            configMap.put(config.getConfigKey(), config.getConfigValue());
        }
        return configMap;
    }

    /**
     * 添加配置集合
     *
     * @param msgRuleDetailConfigDTOList 配置DTO集合
     */
    public void addList(Long msgRuleId, List<MsgRuleDetailConfigDTO> msgRuleDetailConfigDTOList) {
        daqMsgRuleDetailConfigMapper.batchAdd(msgRuleDetailConfigDTOList.stream().map(d -> convertDB(msgRuleId, d)).collect(Collectors.toList()));
    }

    private DaqMsgRuleDetailConfig convertDB(Long msgRuleId, MsgRuleDetailConfigDTO msgRuleDetailConfigDTO) {
        return DaqMsgRuleDetailConfig.builder()
                .msgRuleId(msgRuleId)
                .configKey(msgRuleDetailConfigDTO.getConfigKey())
                .configValue(msgRuleDetailConfigDTO.getConfigValue())
                .build();
    }

    /**
     * 修改消息规则详细配置集合
     *
     * @param msgType
     * @param msgRuleDetailConfigDTOList
     * @return
     */
    public int updateList(Integer msgType, List<MsgRuleDetailConfigDTO> msgRuleDetailConfigDTOList) {
        Assert.notEmpty(msgRuleDetailConfigDTOList, "消息详细配置为空");
        List<MsgRuleConfigFieldBO> msgRuleConfigFieldBOList = this.listMsgRuleConfigFieldBO(msgType);
        Assert.isTrue(msgRuleConfigFieldBOList.size() == msgRuleDetailConfigDTOList.size(), "消息详细配置数量不对");
        Long msgRuleId = msgRuleDetailConfigDTOList.get(0).getMsgRuleId();
        Assert.notNull(msgRuleId, "消息详细配置所属消息规则编号为空");
        Example selectExample = new Example(DaqMsgRuleDetailConfig.class, true, true);
        selectExample.createCriteria().andEqualTo("msgRuleId", msgRuleId).andEqualTo("isDelete", Boolean.FALSE);
        List<DaqMsgRuleDetailConfig> daqMsgRuleDetailConfigList = daqMsgRuleDetailConfigMapper.selectByExample(selectExample);
        int count = daqMsgRuleDetailConfigList.stream().mapToInt(detailConfig -> {
            Optional<MsgRuleDetailConfigDTO> dtoOptional = msgRuleDetailConfigDTOList.stream().filter(c -> c.getId().equals(detailConfig.getId())).findFirst();
            Assert.isTrue(dtoOptional.isPresent(), "没有找到匹配的已存在的详细配置");
            MsgRuleDetailConfigDTO msgRuleDetailConfigDTO = dtoOptional.get();
            if (!detailConfig.getConfigKey().equals(msgRuleDetailConfigDTO.getConfigKey()) || !detailConfig.getConfigValue().equals(msgRuleDetailConfigDTO.getConfigValue())) {
                detailConfig.setConfigKey(msgRuleDetailConfigDTO.getConfigKey());
                detailConfig.setConfigValue(msgRuleDetailConfigDTO.getConfigValue());
                return daqMsgRuleDetailConfigMapper.updateByPrimaryKeySelective(detailConfig);
            }
            return 0;
        }).sum();
        return count;
    }

    /**
     * 获取DTO
     *
     * @param msgRuleId
     * @return
     */
    public List<MsgRuleDetailConfigDTO> listDTO(Long msgRuleId, Integer msgType) {
        Example selectExample = new Example(DaqMsgRuleDetailConfig.class, true, true);
        selectExample.createCriteria().andEqualTo("msgRuleId", msgRuleId).andEqualTo("isDelete", Boolean.FALSE);
        List<DaqMsgRuleDetailConfig> detailConfigList = daqMsgRuleDetailConfigMapper.selectByExample(selectExample);
        return detailConfigList.stream().map(d -> convertDTO(d, msgType)).collect(Collectors.toList());
    }


    /**
     * 获取DTO
     *
     * @param reqDTO
     * @return
     */
    public List<MsgRuleDetailConfigDTO> listDTO(MsgRuleDetailConfigListReqDTO reqDTO) {
        List<MsgRuleConfigFieldBO> msgRuleConfigFieldBOList = listMsgRuleConfigFieldBO(reqDTO.getMsgType());
        return msgRuleConfigFieldBOList.stream().map(this::convertDTO).collect(Collectors.toList());
    }

    /**
     * 获取消息规则配置字段
     *
     * @param msgType
     * @return
     */
    private List<MsgRuleConfigFieldBO> listMsgRuleConfigFieldBO(Integer msgType) {
        Map<String, DataMsgFactory> objectMap = ContextHolder.getBeanOfType(DataMsgFactory.class);
        List<MsgRuleConfigFieldBO> msgRuleConfigFieldBOList = new ArrayList<>();
        objectMap.forEach((s, dataMsgFactory) -> {
            if (msgType.equals(dataMsgFactory.getSupportMsgType().getStatus())) {
                msgRuleConfigFieldBOList.addAll(dataMsgFactory.listRequiredRuleDetailConfigInfo());
            }
        });
        return msgRuleConfigFieldBOList;
    }

    private MsgRuleDetailConfigDTO convertDTO(MsgRuleConfigFieldBO msgRuleConfigFieldBO) {
        MsgRuleDetailConfigDTO msgRuleDetailConfigDTO = new MsgRuleDetailConfigDTO();
        msgRuleDetailConfigDTO.setConfigKey(msgRuleConfigFieldBO.getConfigKey());
        msgRuleDetailConfigDTO.setConfigName(msgRuleConfigFieldBO.getConfigName());
        msgRuleDetailConfigDTO.setDescription(msgRuleConfigFieldBO.getDescription());
        return msgRuleDetailConfigDTO;
    }

    private MsgRuleDetailConfigDTO convertDTO(DaqMsgRuleDetailConfig daqMsgRuleDetailConfig, Integer msgType) {
        List<MsgRuleConfigFieldBO> msgRuleConfigFieldBOList = listMsgRuleConfigFieldBO(msgType);
        Optional<MsgRuleConfigFieldBO> filterResult = msgRuleConfigFieldBOList.stream().filter(c -> c.getConfigKey().equals(daqMsgRuleDetailConfig.getConfigKey())).findFirst();
        MsgRuleDetailConfigDTO msgRuleDetailConfigDTO = new MsgRuleDetailConfigDTO();
        if (filterResult.isPresent()) {
            msgRuleDetailConfigDTO.setConfigName(filterResult.get().getConfigName());
            msgRuleDetailConfigDTO.setDescription(filterResult.get().getDescription());
        }
        msgRuleDetailConfigDTO.setConfigKey(daqMsgRuleDetailConfig.getConfigKey());
        msgRuleDetailConfigDTO.setConfigValue(daqMsgRuleDetailConfig.getConfigValue());
        msgRuleDetailConfigDTO.setMsgRuleId(daqMsgRuleDetailConfig.getMsgRuleId());
        msgRuleDetailConfigDTO.setId(daqMsgRuleDetailConfig.getId());

        return msgRuleDetailConfigDTO;
    }

    /**
     * 删除消息规则详细配置
     *
     * @param msgRuleId
     */
    public void delete(Long msgRuleId) {
        daqMsgRuleDetailConfigMapper.deleteRule(msgRuleId);
    }
}
